<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>

        var obj = {
            id: 1,
            pname: '小米',
            price: 3999
        }
        // 以前的对象添加和修改属性的方式
        // obj.num = 1000//添加新属性
        // obj.price = 99//修改
        // console.log(obj);

        // Object.defineProperty(目标对象,目标属性,属性说明:以对象形式{}书写) 三个参数
        // Object.defineProperty(obj,prop,descriptor{})
        // Object.defineProperty主要用途:定义新属性或修改原有属性

        // defineProperty()第三个参数descriptor内的四个参数说明descriptor {value, wirtable, enumerable,configurable}
        // 如下: 

        //1. descriptor之value
        //value的值不受数据类型限制 默认为undefined
        //(1)原对象没有num 则为个对象添加属性及属性值
        //(2)原对象已有price属性则为修改原属性值
        Object.defineProperty(obj, 'num', {
            value: 1000,
        })
        Object.defineProperty(obj, 'price', {
            value: 9.9,
        })
        // console.log(obj);

        //2.descriptor之wirtable
        //(1)原对像已有的属性写或不写该参数都默认为true(可修改) 除非手动修改为false
        //(2)后增加属性写或不写该参数都默认为false(不可修改) 除非手动修改为true
        Object.defineProperty(obj, 'id', {
            // writable: false
            // writable: true,
        })
        obj.id = 2//(3)取决于writable的状态决定能被否修改
        // console.log(obj)


        //3.descriptor之enumerable
        //(1)原对像已有的属性写或不写该参数都默认为true(可遍历) 除非手动修改为false
        //(2)后增加属性写或不写该参数都默认为false(不可遍历) 除非手动修改为true
        // Object.defineProperty(obj, 'address', {
        //     enumerable: false
        //     enumerable: true
        // })
        // var arr = Object.keys(obj)
        // console.log(arr);//取决于enumerable的状态决定可遍历输出的属性。


        //4.descriptor之configurable 
        //(1)原对像已有的属性写或不写该参数都默认为true(可删除) 除非手动修改为false
        //(2)后增加属性写或不写该参数都默认为false(不可删除) 除非手动修改为true 
        Object.defineProperty(obj, 'address', {
            value: '新增加的属性默认不可被修改',
            enumerable: true,
            writable: true,
            configurable: false,

        })
        obj.address = '可以被修改吗？'
        console.log(Object.keys(obj));
        //额外知识点:delete 删除对象属性(不加点和括号) 用一个空格隔开 delete 对象.要删除的属性
        delete obj.address
        delete obj.pname


        //5.descriptor之configurable
        //额外注意点
        //configurable为false时不可修改该属性其余参数的状态(特性)
        Object.defineProperty(obj, 'address', {
            value: '新增加的属性默认不可被修改',
            // 报错 上面address.configurable已为false
            // enumerable: false,
            // writable: false,
        })
        console.log(obj);

        // 总结
        // 此总结针对的是defineProperty()内第三个参数(说明参数:)descriptor内的四个参数说明:
        // 原对象已存在的属性 他们的说明参数写或不写都为true(可修改/可遍历/可删除) 除非手动修改为false
        // 新添加的属性 他们的说明参数写或不写都为false(不可修改/不可遍历/不可删除) 除非手动修改为true
        // 额外注意
        // 属性的configurable参数如果已为false不仅不可删除 且不允许在修改该属性其余参数里面的状态(特性)
    </script>
</body>

</html>